package my12306;

import java.util.List;
import my12306.bean.PassengerInfo;
import my12306.bean.QueryResult;
import my12306.bean.Tokens;
import my12306.http.Consts;
import my12306.http.TrainInfo;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 */
public class AutoThread extends Thread {

    private final TrainClient trainClient = My12306App.getTrainClient();
    private final My12306View view = (My12306View) My12306App.getApplication().getMainView();
    private final Logger log = LoggerFactory.getLogger(getClass());
    List<PassengerInfo> users;
    TrainInfo bestTrain;

    /**
     *
     */
    public AutoThread(List<PassengerInfo> users, TrainInfo bestTrain) {
        this.users = users;
        this.bestTrain = bestTrain;
    }
    private boolean stop = false;
    private final Object waitLock = new Object();

    void continueRun() {
        synchronized (waitLock) {
            waitLock.notifyAll();
        }
    }

    private void waitForSignal() {
        synchronized (waitLock) {
            try {
                waitLock.wait();
            } catch (InterruptedException ie) {
                // continue
            }
        }
    }

    public void setStop() {
        stop = true;
        continueRun();
    }

//    public void login() {
//        //<editor-fold defaultstate="collapsed" desc=" 1. Login "> 
//        QueryResult qr;
//        int count = 0;
//        String loginRand;
//        String randCode;
//        do {
//            try {
//                log(""+trainClient.getCurrentUser()); //$NON-NLS-1$
//                randCode = trainClient.getRandCodeDailog(Constants.LOGIN_CODE_URL);//弹出识别对话框
//
//                loginRand = trainClient.loginAction_loginAysnSuggest();
//
//                if (loginRand == null || randCode == null || randCode.isEmpty() || loginRand.isEmpty()) {
//                    continue;
//                }
//
//                qr = trainClient.login(rob.getUsername(), rob.getPassword(), randCode, loginRand);
//                if (qr.getState() == QueryResult.SUCC) {
//                    rob.console(qr.getMsg());
//                } else if (qr.getState() == QueryResult.RAND_CODE_ERROR) {
//                    rob.console(Constants.CODE_ERROR);
//                    continue;
//                } else if (qr.getState() == QueryResult.ACC_ERROR
//                        || qr.getState() == QueryResult.PWD_ERROR) {
//                    rob.console(Constants.USER_ERR);
//                    return;
//                } else {
//                    rob.console(qr.getMsg());
//                }//113,"当前访问用户过多,请重新登录"
//                if (trainClient.isLoginOk()) {
//                    break;
//                } else {
//                    Thread.sleep(Config.getSleepTime());
//                }
//                count++;
//            } catch (Exception ex) {
//                log.error(ex.getMessage(), ex);
//            }
//        } while (!trainClient.isLoginOk() && !stop);
//
////</editor-fold> 
//    }
    void log(String msg) {
        log.info(msg);
        view.log(msg);
    }

    String getJsonValue(JSONObject json, String key) {
        String result = null;
        try {
            result = json.get(key).toString();
        } catch (Exception ex) {
            result = "";
        }

        return result;
    }

    @Override
    public void run() {
        log("\r\n自动订票开始。");
        stop = false;
        while (!stop) {
            if (!bestTrain.getMeta().isValidate()) {
                log("此班列车不能预定。");
                break;
//                throw new OrderException("此班列车不能预定。");
            }
            if (!trainClient.isLoginOk()) {
                log("没有登录。");
                break;
//                throw new OrderException("没有登录。");
            }

            //<editor-fold defaultstate="collapsed" desc=" 3. search & book ">                

            log("开始预定。");
            String id = "" + System.currentTimeMillis();
            String url;
            String ticket;
            String token;
            Tokens tokens;
            String randCode = null;

            QueryResult qr;
            my12306.http.JSONObject json;
            org.json.JSONObject json2;

            StringBuilder sb = new StringBuilder();
            sb.append("你选择的车票是： \r\n")
                    .append(bestTrain.getTrainCode()).append("\r\n\t发站 ")
                    .append(bestTrain.getFromStation()).append("\t到站 ")
                    .append(bestTrain.getToStation()).append("\r\n 发时 ")
                    .append(bestTrain.getSetoutTime()).append("\t 到时 ")
                    .append(bestTrain.getArriveTime()).append("\t 历时 ")
                    .append(bestTrain.getPeriod());
            log(sb.toString());

            //<editor-fold defaultstate="collapsed" desc=" step 1 "> 

            qr = trainClient.querySingleAction_init();
            tokens = trainClient.confirmPassengerAction_init().getTokens();

            //step 1-1  post submutOrderRequest
            url = "https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=submutOrderRequest";
            qr = trainClient.querySingleAction_submutOrderRequest_step1_1("00:00--24:00", bestTrain);
//            trainClient.writetoFile("e:\\test\\" + id + "_1_step1_1", qr.getRawData());

            if (qr.getState() != QueryResult.SUCC) {
                log("error: step 1-1 submutOrderRequest");
                continue;
            }

            if (qr.getMsg().contains(bestTrain.getTrainNo())) {
                log("step 1-1 SubmutOrderRequest ok");
            } else {
                log("step 1-1 SubmutOrderRequest" + qr.getMsg());
            }



            // step 1-0 init
//        qr = trainClient.confirmPassengerAction_init();
//        //https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=init
//        token = trainClient.getQueryToken();
//        log("token" + token);
//        if (token == null || token.isEmpty()) {
//            log("token is empty. please retry.");
////            return;
//        }

            //step 1-2  get tokens  
            tokens = trainClient.getTokensFromHtml(qr.getRawData());
//        tokens=trainClient.confirmPassengerAction_init().getTokensFromUrl();
//        qr = trainClient.confirmPassengerAction_init();
//        Tokens tokens2 = trainClient.getTokensFromUrl(referQuerySingleAction);
//        tokens = trainClient.getTokensFromHtml(qr.getRawData());
//        token = trainClient.getQueryToken();//https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=init
//        tokens.setToken(token);
//        tokens = trainClient.getTokensFromUrl(referQuerySingleAction);
//            log("ticket：" + tokens.getTokensFromUrl());
            if (tokens.getTicket() == null || tokens.getTicket().isEmpty()) {
                log("ticket is empty. please retry.");
                return;
            }
//            log("token：" + tokens.getToken());
            if (tokens.getToken() == null || tokens.getToken().isEmpty()) {
                log("token is empty. please retry.");
                return;
            }
//            log("bedlevel：" + tokens.getBedlevel());
            if (tokens.getBedlevel() == null || tokens.getBedlevel().isEmpty()) {
                log("bedlevel is empty. please retry.");
                return;
            }

            qr = trainClient.confirmPassengerAction_getpassengerJson();

//        boolean eq = token.equals(tokens.getToken());
//        if (token != null && !token.isEmpty()) {
//            tokens.setToken(token);
//        }
            //</editor-fold>  

            //<editor-fold defaultstate="collapsed" desc=" step 2 ">  
            //step2-1 checkOrderInfo

            do {
                randCode = trainClient.getRandCodeDailog(Consts.URL_passCodeAction_rand_order);

                if (randCode == null || randCode.isEmpty()) {
                    break;
                }
                url = "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=checkOrderInfo&rand=";
                qr = trainClient.confirmPassengerAction_checkOrderInfo_step2_1(randCode, tokens, users, bestTrain);
                /*"{"checkHuimd":"Y","check608":"Y","msg":"","errMsg":"Y"}" 
                 * {"checkHuimd":"Y","check608":"Y","msg":"","errMsg":"Y"}    
                 * {"checkHuimd":"N","check608":"Y","msg":"对不起，由于您取消次数过多，今日将不能继续受理您的订票请求！","errMsg":"Y"} 
                 */
//                trainClient.writetoFile("e:\\test\\" + id + "_2_step2_1", qr.getRawData());

                if (qr.getState() != QueryResult.SUCC) {
                    log(qr.getMsg());
                    log("2-1:1 CheckOrderInfo error" + qr.getMsg());
                    continue;
                }
                log("2-1: CheckOrderInfo result:\r\n " + qr.getMsg());
                json = new my12306.http.JSONObject(qr.getRawData());

                if (json.get("msg") == null || json.get("errMsg") == null) {
                    log(qr.getMsg());
                    log("2-1:2 checkOrderInfo error" + qr.getMsg());
                    continue;
                } else if (json.get("msg").isEmpty() && json.get("errMsg").equals("Y")) {
                    log("2-1: checkOrderInfo ok .");
                    break;
                } else if (json.get("checkHuimd") != null && json.get("checkHuimd").equals("N")) {
                    //"对不起，由于您取消次数过多，今日将不能继续受理您的订票请求！
                    log(json.get("msg"));
                    return;
                } else if (json.get("check608") != null && json.get("check608").equals("N")) {
                    //"本车为实名制列车，实行一日一车一证一票制！
                    log(json.get("msg"));
                    return;
                } else if (qr.getRawData().contains("输入的验证码不正确！")) {
                    log("2-1: " + json.get("errMsg"));
                    continue;
                } else {
                    log(json.get("msg") + json.get("errMsg"));
                    continue;
//                    throw new OrderException(json.get("msg"));
                }
            } while (!stop);

            if (randCode == null || randCode.isEmpty()) {
                log("输入错误，准备退出。");
                stop = true;
                break;
            }

            //step2-2
            //https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=getQueueCount&train_date=2013-01-27&train_no=6300000L3210&station=L32&seat=1&from=GZQ&to=ZZF&ticket=10169030001016900003

            /*"{"countT":0,"count":1132,"ticket":"10000038001000000001","op_1":true,"op_2":false}"  
             * "{"countT":0,"count":25,"ticket":"10000039561000000000","op_1":true,"op_2":false}"                     * 
             * "{"countT":0,"count":0,"ticket":"","op_1":false,"op_2":true}"
             * "{"countT":0,"count":0,"ticket":"O065600135M1050001059207300012","op_1":false,"op_2":false}"
             * "{"countT":0,"count":0,"ticket":"O065300528M1046001079206400012","op_1":false,"op_2":true}"
             * "{"countT":0,"count":0,"ticket":"O065300748M1046001189206400012","op_1":false,"op_2":false}"
             * "{"countT":0,"count":1,"ticket":"O065300687M1046001179206400012","op_1":false,"op_2":false}"
             */
            qr = trainClient.confirmPassengerAction_getQueueCount_step2_2(bestTrain, users.get(0).getSeatType(), tokens.getTicket());
//            trainClient.writetoFile("e:\\test\\" + id + "_2_step2_2", qr.getRawData());
            log("2-2: GetQueueCount result:\r\n" + qr.getMsg());
            if (qr.getState() != QueryResult.SUCC) {
                log("2-2: GetQueueCount error" + qr.getMsg());
                continue;
            }
            try {
                json2 = new JSONObject(qr.getRawData());
                if (getJsonValue(json2, "op_2").equals("true")) {
                    //目前排队人数已经超过余票张数，请您选择其他席别或车次，特此提醒。                    
                    log("2-2: getQueueCount: 目前排队人数已经超过余票张数，请您选择其他席别或车次，特此提醒。");
                    continue;
                } else {
                    log("2-2: getQueueCount: " + "目前排队人数： " + getJsonValue(json2, "countT") + " 人，特此提醒。");
                }

            } catch (JSONException ex) {
                log.error(ex.getLocalizedMessage(), ex);
            }


            //</editor-fold>

            //<editor-fold defaultstate="collapsed" desc=" step 3 ">    

            //step3-1
            url = "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=confirmSingleForQueueOrder";
            qr = trainClient.confirmPassengerAction_confirmSingleForQueueOrder_step3_1(randCode, tokens, users, bestTrain);
            /*"{"errMsg":"非法的订票请求！"}"   
             * {"errMsg":"Y"}    
             * "{"errMsg":"包含未付款订单","errCode":"FAIL"}"
             //"{"errMsg":"排队人数现已超过余票数，请您选择其他席别或车次。","errCode":"MORE"}"
             * "{"errMsg":"包含排队中的订单","errCode":"FAIL"}"
             * "{"errMsg":"请不要重复提交！"}"
             */
//            trainClient.writetoFile("e:\\test\\" + id + "_3_step3_1", qr.getRawData());
            log("3-1: ConfirmSingleForQueueOrder result:\r\n" + qr.getMsg());
            if (qr.getState() != QueryResult.SUCC) {
                log(qr.getMsg());
                continue;
            }
            json = new my12306.http.JSONObject(qr.getRawData());
            if (json.get("errMsg") == null) {
                log("exception, continue");
                continue;
            }
            if (!json.get("errMsg").equals("Y")) {
                if (json.get("errMsg").contains("排队人数现已超过余票数，请您选择其他席别或车次。")) {
                    log(json.get("errMsg"));
                    continue;
                } else if (json.get("errMsg").contains("请不要重复提交！")) {
                    log(json.get("errMsg"));
                    log("正在取消。");
                    trainClient.confirmPassengerAction_cancel(randCode, tokens, users, bestTrain);
                    continue;
                } else {
                    log(json.get("errMsg"));
//                throw new OrderException(json.get("errMsg"));
//                    return;
                }
            }
            log("订票成功。");

            //step3-2
            url = "https://dynamic.12306.cn/otsweb/order/myOrderAction.do?method=getOrderWaitTime&tourFlag=dc";
            qr = trainClient.myOrderAction_getOrderWaitTime_3_2(bestTrain, randCode, tokens.getTicket());
            /*"{"tourFlag":"dc","waitTime":-2,"waitCount":0,"requestId":5694723412608919774,"errorcode":"0","msg":"对不起，由于您取消次数过多，今日将不能继续受理您的订票请求。1 月10日您可继续使用订票功能。","count":0}"
             //"{"tourFlag":"dc","waitTime":-1,"waitCount":0,"orderId":"E412621130","requestId":5694347419390027998,"count":0}" 
             * "{"tourFlag":"dc","waitTime":-1,"waitCount":0,"orderId":"E463163211","requestId":5694315136385788126,"count":0}"  
             * "{"tourFlag":"dc","waitTime":-1,"waitCount":0,"orderId":"E463163211","requestId":5694315136385788126,"count":0}"
             * {"tourFlag":"dc","waitTime":5,"waitCount":0,"requestId":5694285137440123102,"count":0}
             * "{"tourFlag":"dc","waitTime":-2,"waitCount":0,"requestId":5696091164217157854,"msg":"没有足够的票!","count":0}"
             * "{"tourFlag":"dc","waitTime":-1,"waitCount":0,"orderId":"E471747429","requestId":5696109459540519134,"count":0}"
             */
//            trainClient.writetoFile("e:\\test\\" + id + "_3_step3_2", qr.getRawData());

            if (qr.getState() != QueryResult.SUCC) {
                log(qr.getMsg());
                continue;
            }
            log("3-2: GetOrderWaitTime result: \r\n" + qr.getMsg());
            json = new my12306.http.JSONObject(qr.getRawData());

            if (json.get("msg") != null) {
                log(json.get("msg"));
            }

            //step3-3 get order id
            do {
                url = "https://dynamic.12306.cn/otsweb/order/myOrderAction.do?method=getOrderWaitTime&tourFlag=dc";
//                qr = trainClient.doGet(url, referConfirmPassengerAction);
                qr = trainClient.myOrderAction_getOrderWaitTime_3_2(bestTrain, randCode, tokens.getTicket());
                //{"tourFlag":"dc","waitTime":-1,"waitCount":0,"orderId":"E431559501","requestId":5694285137440123102,"count":0}
                //"{"tourFlag":"dc","waitTime":-4}"
                json = new my12306.http.JSONObject(qr.getRawData());
//                trainClient.writetoFile("e:\\test\\" + id + "_3_step3_3", qr.getRawData());
                
                if (qr.getState() != QueryResult.SUCC) {
                    log(qr.getMsg());
                    continue;
                }
                log("3-3: GetOrderWaitTime result: \r\n" + qr.getMsg());
                if (json.get("msg") != null) {
                    log(json.get("msg"));
                    throw new OrderException(json.get("msg"));
                }
                if (json.get("orderId") == null || json.get("orderId").isEmpty()) {
                    log("orderId: is empty");
                    continue;
                } else {
                    break;
                }

            } while (true);
            //step3-4 payorder
            //post https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=payOrder&orderSequence_no=E431559501
            url = "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=payOrder&orderSequence_no=";

            qr = trainClient.confirmPassengerAction_payOrder_step3_4(json.get("orderId"), randCode, tokens, users, bestTrain);
            //席位已成功锁定，请在<b>45</b>分钟内完成网上支付，否则系统将自动取消本次交易。
            //"消息提示 系统忙！ 请点击我的订单确认客票的状态后再尝试后续操作。谢谢！"
//            trainClient.writetoFile("e:\\test\\" + id + "_3_step3_4", qr.getRawData());

            if (qr.getMsg().contains("席位已成功锁定")) {
                log("席位已成功锁定，请在<b>45</b>分钟内完成网上支付，否则系统将自动取消本次交易。");
                stop = true;
                break;
            } else if (qr.getMsg().contains("系统忙")) {
                log("系统忙。");
                continue;
//            Thread.currentThread().sleep(Config.getSleepTime());

            } else {
                log("订票失败，重新开始。");
                continue;
            }

            //</editor-fold>


            //</editor-fold>  

        }
        stop = true;
        log("自动订票结束。\r\n");
    }
}
